package app.ui;

import java.awt.Component;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JPanel;

import app.action.PerformKeyAction;

public abstract class AbsCommonPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6174234925136752839L;
	
	protected int btnWid = 120;
	protected int btnHei = 25;
	
	protected AbsMainFrame mFrame;
	protected CommonPanelAction commonPanelAction;
	protected PerformKeyAction keyAction;
	private boolean addedToMainFrame = false;

	public AbsCommonPanel(AbsMainFrame mFrame) {
		super(null);
		this.mFrame = mFrame;

		this.keyAction = new PerformKeyAction(this);
	}
	/**
	 * Construct the components and add they to this panel
	 */
	protected abstract void addComponents();
	
	/**
	 * Initialize the states of components.
	 */
	protected abstract void initializeComponents();
	
	/**
	 * Set components' bound to arrange they. 
	 */
	protected abstract void resizeComponents();

	public void makeThisAutoResize() {
		// ---------------------------------------------------------------------
		// add and arrange the components
		this.addComponents();
		this.initializeComponents();		
		// ---------------------------------------------------------------------

		// ---------------------------------------------------------------------
		// automatically resize components.
		this.commonPanelAction = new CommonPanelAction(this);
		this.addComponentListener(commonPanelAction);

		// add key action
		Component[] components = this.getComponents();
		for (Component comp : components) {
			comp.addKeyListener(keyAction);
		}
		// ---------------------------------------------------------------------

		// ---------------------------------------------------------------------
		// mark this is added
		this.addedToMainFrame = true;
		// ---------------------------------------------------------------------
	}

	public void close(boolean removeThis) {
		this.setVisible(false);

		// remove this from main frame
		if (removeThis) {
			mFrame.remove(this);

			// mark this is removed
			this.addedToMainFrame = true;
		}
	}
	
	/**
	 * This method will automatically add the panel to the main
	 * frame if this is not added. 
	 */
	public void open() {
		if (!addedToMainFrame) {
			mFrame.add(this);
		}

		this.setVisible(true);
	}

	public AbsMainFrame getmFrame() {
		return mFrame;
	}

	public CommonPanelAction getCommonPanelAction() {
		return commonPanelAction;
	}

	public PerformKeyAction getKeyAction() {
		return keyAction;
	}
}

class CommonPanelAction extends ComponentAdapter {
	private AbsCommonPanel mPanel;
	private JPanel currentDisplayPanel;

	public CommonPanelAction(AbsCommonPanel mPanel) {
		super();
		this.mPanel = mPanel;
	}

	@Override
	public void componentResized(ComponentEvent e) {
		mPanel.resizeComponents();
	}

	@Override
	public void componentShown(ComponentEvent e) {
		getCurrentDisplayPanel();
	}

	@Override
	public void componentHidden(ComponentEvent e) {
		if (currentDisplayPanel != null) {
			currentDisplayPanel.setVisible(true);
		}
	}

	/**
	 * Catch the current panel displayed on main frame set other components
	 * invisible
	 */
	private void getCurrentDisplayPanel() {
		Component[] components = mPanel.getmFrame().getContentPane()
				.getComponents();
		AbsCommonPanel panel = null;
		for (Component comp : components) {
			if (comp instanceof AbsCommonPanel) {
				panel = (AbsCommonPanel) comp;
			}

			if (comp.isVisible()) {
				this.currentDisplayPanel = (JPanel) comp;
				if (panel != mPanel) {
					comp.setVisible(false);
				}
			}

		}
	}

}
